package com.kasax.ipcbus.corel;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.TextUtils;

import com.kasax.ipcbus.IpcBusService;
import com.kasax.ipcbus.bean.Request;
import com.kasax.ipcbus.bean.Response;
import com.kasax.ipcbus.utils.LogUtils;

import java.util.concurrent.ConcurrentHashMap;

public class ServiceConnectManager {
    private static volatile ServiceConnectManager sInstance = new ServiceConnectManager();
    /**
     * 连接缓存: Class+ServiceConnection
     */
    private ConcurrentHashMap<Class, CoreServiceConnection> mServiceConnectionMap = new ConcurrentHashMap<>();

    /**
     * Binder缓存池
     */
    private ConcurrentHashMap<Class, IpcBusService> mBinderMap = new ConcurrentHashMap<>();

    private ServiceConnectManager() {

    }

    public static ServiceConnectManager getInstance() {
        return sInstance;
    }


    public void bind(Context context, String pkgName, Class<CorelService> serviceClass) {
        LogUtils.i(getClass(), "bind pkgName: " + pkgName + " , serviceClass: " + serviceClass);
        CoreServiceConnection coreServiceConnection = new CoreServiceConnection(serviceClass);
        mServiceConnectionMap.put(serviceClass, coreServiceConnection);
        Intent intent;
        if (TextUtils.isEmpty(pkgName)) {
            intent = new Intent(context, serviceClass);
        } else {
            intent = new Intent();
            intent.setClassName(pkgName, serviceClass.getName());
        }
        context.bindService(intent, coreServiceConnection, Context.BIND_AUTO_CREATE);
        LogUtils.i(getClass(), "bind pkgName: " + pkgName + " , serviceClass: " + serviceClass + " complete");
    }

    /***
     * 发起请求
     * @param corelServiceClass
     * @param request
     * @return
     */

    public Response request(Class<CorelService> corelServiceClass, Request request) {
        // 获取Binder对象
        IpcBusService ipcBusService = mBinderMap.get(corelServiceClass);
        if (ipcBusService != null) {
            try {
                Response response = ipcBusService.send(request);
                LogUtils.i(getClass(), "request response: " + response);
                return response;
            } catch (RemoteException e) {
                LogUtils.e(getClass(), e);
            }
        }
        return null;
    }

    private class CoreServiceConnection implements ServiceConnection {

        private final Class<CorelService> mServiceCls;

        public CoreServiceConnection(Class<CorelService> serviceClass) {
            this.mServiceCls = serviceClass;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            IpcBusService ipcBusService = IpcBusService.Stub.asInterface(service);
            mBinderMap.put(mServiceCls, ipcBusService);
            LogUtils.i(getClass(), "onServiceConnected serviceClass: " + mServiceCls);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            LogUtils.i(getClass(), "onServiceDisconnected serviceClass: " + mServiceCls);
            mBinderMap.remove(mServiceCls);
        }
    }
}
